{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![MLU Logo](../data/MLU_Logo.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# <a name=\"0\">Machine Learning Accelerator - Natural Language Processing - Lecture 3</a>\n",
    "\n",
    "## Neural Networks with PyTorch\n",
    "\n",
    "In this notebook, we will build, train and validate a Neural Network using PyTorch.\n",
    "1. <a href=\"#1\">Implementing a neural network with PyTorch</a>\n",
    "2. <a href=\"#2\">Loss Functions</a>\n",
    "3. <a href=\"#3\">Training</a>\n",
    "4. <a href=\"#4\">Example - Binary Classification</a>\n",
    "5. <a href=\"#5\">Natural Language Processing Context</a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. <a name=\"1\">Implementing a neural network with PyTorch</a>\n",
    "(<a href=\"#0\">Go to top</a>)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's implement a simple neural network with two hidden layers of size 64 and 128 using the sequential mode (Adding things in sequence). We will have 3 inputs, 2 hidden layers and 1 output layer. Some drop-outs attached to the hidden layers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-01-09T14:42:26.315306Z",
     "start_time": "2021-01-09T14:42:25.876374Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sequential(\n",
      "  (0): Linear(in_features=3, out_features=64, bias=True)\n",
      "  (1): Tanh()\n",
      "  (2): Dropout(p=0.4, inplace=False)\n",
      "  (3): Linear(in_features=64, out_features=64, bias=True)\n",
      "  (4): Tanh()\n",
      "  (5): Dropout(p=0.3, inplace=False)\n",
      "  (6): Linear(in_features=64, out_features=1, bias=True)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "from torch import nn\n",
    "\n",
    "net = nn.Sequential(\n",
    "        nn.Linear(in_features=3,       # Input size of 3 is expected\n",
    "                  out_features=64),    # Linear layer-1 with 64 units\n",
    "        nn.Tanh(),                     # Tanh activation is applied\n",
    "        nn.Dropout(p=.4),              # Apply random 40% drop-out to layer_1\n",
    "        nn.Linear(64, 64),             # Linear layer-2 with 64 units  \n",
    "        nn.Tanh(),                     # Tanh activation is applied\n",
    "        nn.Dropout(p=.3),              # Apply random 30% drop-out to layer_2\n",
    "        nn.Linear(64,1))               # Output layer with single unit\n",
    "\n",
    "print(net)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can initialize the weights of the network with 'initialize()' function. We prefer to use the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-01-09T14:42:26.323790Z",
     "start_time": "2021-01-09T14:42:26.316902Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Sequential(\n",
       "  (0): Linear(in_features=3, out_features=64, bias=True)\n",
       "  (1): Tanh()\n",
       "  (2): Dropout(p=0.4, inplace=False)\n",
       "  (3): Linear(in_features=64, out_features=64, bias=True)\n",
       "  (4): Tanh()\n",
       "  (5): Dropout(p=0.3, inplace=False)\n",
       "  (6): Linear(in_features=64, out_features=1, bias=True)\n",
       ")"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def xavier_init_weights(m):\n",
    "    if type(m) == nn.Linear:\n",
    "        torch.nn.init.xavier_uniform_(m.weight)\n",
    "\n",
    "net.apply(xavier_init_weights)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's look at our layers and dropouts on them. We can easily access them wth net[layer_index]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-01-09T14:42:26.329940Z",
     "start_time": "2021-01-09T14:42:26.326430Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Linear(in_features=3, out_features=64, bias=True)\n",
      "Tanh()\n",
      "Dropout(p=0.4, inplace=False)\n",
      "Linear(in_features=64, out_features=64, bias=True)\n",
      "Tanh()\n"
     ]
    }
   ],
   "source": [
    "print(net[0])\n",
    "print(net[1])\n",
    "print(net[2])\n",
    "print(net[3])\n",
    "print(net[4])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. <a name=\"2\">Loss Functions</a>\n",
    "(<a href=\"#0\">Go to top</a>)\n",
    "\n",
    "We can select [loss functions](https://d2l.ai/chapter_linear-networks/linear-regression.html#loss-function) according to our problem. A full list of supported `Loss` functions in PyTorch are available [here](https://pytorch.org/docs/stable/nn.html#loss-functions). \n",
    "\n",
    "Let's go over some popular loss functions and see how to call a built-in loss function:\n",
    "\n",
    "\n",
    "__Binary Cross-entropy Loss:__ A common used loss function for binary classification. \n",
    "\n",
    "```python\n",
    "loss = nn.BCELoss()\n",
    "```\n",
    "\n",
    "__Categorical Cross-entropy Loss:__ A common used loss function for multi-class classification. \n",
    "\n",
    "```python\n",
    "loss = nn.CrossEntropyLoss()\n",
    "```\n",
    "\n",
    "__MSE Loss:__ One of the most common loss functions for regression problems. \n",
    "\n",
    "```python\n",
    "loss = nn.MSELoss()\n",
    "```\n",
    "\n",
    "__L1 Loss:__ This is similar to L2 loss. It measures the abolsute difference between target values (y) and predictions (p).\n",
    "$$\n",
    "\\mathrm{L1 loss} = \\frac{1}{2} \\sum_{examples}|y - p|\n",
    "$$\n",
    "In pytorch, we can use it with `L1Loss`:\n",
    "```python\n",
    "loss = nn.L1Loss()\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. <a name=\"3\">Training</a>\n",
    "(<a href=\"#0\">Go to top</a>)\n",
    "\n",
    "`torch.optim` module provides necessary optimization algorithms for neural networks. We can use the following `Optimizers` to train a network using [Stochastic Gradient Descent (SGD)](https://d2l.ai/chapter_optimization/sgd.html) method and learning rate of 0.001.\n",
    "\n",
    "```python\n",
    "from torch import optim\n",
    "optimizer = optim.SGD(net.parameters(), lr=0.001)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. <a name=\"4\">Example - Binary Classification</a>\n",
    "(<a href=\"#0\">Go to top</a>)\n",
    "\n",
    "Let's train a neural network on a random dataset. We have two classes and will learn to classify them."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-01-09T14:42:26.750569Z",
     "start_time": "2021-01-09T14:42:26.332404Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "from sklearn.datasets import make_circles\n",
    "\n",
    "X, y = make_circles(n_samples=750, shuffle=True, random_state=42, noise=0.05, factor=0.3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's plot the dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-01-09T14:42:27.482480Z",
     "start_time": "2021-01-09T14:42:26.752160Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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kzg8513eeP0ZOBERERGpxMCJiIiIAABHjhyBTqdDaWmpt5visxg4ERERkU9YtmwZBg4ciKioKOh0Op8s9cDAiYiIyIsMBqC4GFizRv40GLzdIu+5dOkSBg8ejBdeeMHbTbGKgRMREZGXFBYCaWlARgYwerT8mZYmt7tLQ0MD5syZg6uvvhrh4eHo0KEDZs2aZXFfg8GARx99FOnp6WjVqhW6du2KhQsXmuxTXFyM3r17o02bNmjXrh1uueUWlJeXAwC+++47ZGRkIDIyElFRUejVqxf27NljtW25ubl4/vnn0adPH+2esMZYx4mIiMgLCguBYcMA84XPKirk9o8/BrKztX/c6dOnY/ny5Zg/fz5uvfVWnDx5Evv377e4b0NDA1JSUrB+/XrExcVh586dePzxx5GcnIwHH3wQ9fX1uO+++zBu3DisWbMGdXV1+Pe//9042+2hhx5Cz549sWTJEoSEhKC0tBShoaHaPykPYuBERETkYQYD8MwzzYMmQG7T6YDcXCArC9CyruP58+excOFCLF68GDk5OQCATp064dZbb7W4f2hoKPLz8xt/T09Px86dO7F+/Xo8+OCDqKmpgV6vx7333otOnToBALp37964/9GjR/Hss8+iW7duAIDOnTtr92S8hEN1REREHrZjB3D8uPW/CwEcOyb309JPP/2E2tpaDBo0SPUxS5cuxY033oj4+Hi0bdsWy5cvx9GjRwEAMTExGDt2LO666y4MHToUCxcuxMmTJxuPnTJlCh577DHccccdePXVV3H48GFtn5AXMHAiIiLyMKPYQpP91FKWKVFr/fr1mDx5Mv785z9j06ZNKC0txSOPPIK6urrGfVauXImSkhL069cP69atQ5cuXbBr1y4AQF5eHn788UcMGTIEX331Fa655hps2LBB0+fkaQyciIiIPEztmrRar13buXNntGrVClu3blW1/44dO9CvXz9MnDgRPXv2xNVXX22x16hnz56YPn06du7ciR49emD16tWNf+vSpQsmT56MTZs2ITs7GytXrtTs+XgDAyciIiIP698fSEmRuUyW6HRAaqrcT0sRERF47rnnMG3aNLz//vs4fPgwdu3ahRUrVljc/+qrr8aePXvwj3/8Az///DNeeukl7N69u/HvZWVlmD59OkpKSlBeXo5Nmzbh559/Rvfu3XH58mVMmjQJxcXFKC8v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djaQlcXK4X4koHucLBk6dCh0Oh0++eQTi39njxMREdmjWY8TuYR1nDygT58+OHjwoNW/h4eHIyoqyuRGREREBARh4LR3714kazy9k4iIiIKDX+U4XbhwAYcOHWr8vaysDKWlpYiJiUGHDh0wffp0VFRU4P333wcALFiwAGlpafjDH/6Auro6fPDBBygoKEBBQYG3ngIREQUQP812CRjeeP39KnDas2ePyYy4KVOmAABycnKwatUqnDx5srEMPADU1dVh6tSpqKioQKtWrfCHP/wBn332Ge655x6Pt52IiAKHUs360qVLDlfjJu1cunQJADxaXdxvk8M9hYv8EhGRJSdPnsS5c+eQkJCA1q1bQ2etmCVpTgiBS5cuoaqqCu3atbOYgsNyBERERD4kKSkJAFBVVeXllgSvdu3aNZ4HT2HgRERE5ASdTofk5GQkJCTg999/93Zzgk5oaChCvFDvioETERGRC0JCQrxyASfvCLpyBERERETOYuBEREREpBIDJyIiIiKVGDgRERERqcTAiYiIiEglBk5EREREKjFwIiIiIlKJgRMRERGRSgyciIiIiFRi4ERERESkEgMnIiIiIpUYOBERERGpxMCJiIiISCUGTkREREQqMXAiIiIiUomBExEREZFKDJyIiIiIVGLgRERERKQSAyciIiIilRg4EREREanEwImIiIhIJQZORERERCoxcCIiIiJSiYETERERkUoMnIiIiIhUauntBhARuY3BAOzYAZw8CSQnA/37AyEh3m4VEfkxBk5EFJgKC4FnngGOH2/alpICLFwIZGc3399SkAUw8CIiEwyciMi3aNFLVFgIDBsGCGG6vaJCbv/4Y9PgyVKQFRsrf54507TNVuBFREFBJ4T5/yxkrKamBtHR0dDr9YiKivJ2c4gCm6O9RJYYDEBiomnAY0ynk/dZViYDMmtBlrVjgeaBFxH5HHddv5kcTkS+QQlgjIMmQP4+bJj8uxqzZlkPmgAZIB07Jnu1DAYZqKn9/qjsl5srj3UXgwEoLgbWrJE/3flYROQQ9jjZwR4nIg8wGIC0tOZBk7HYWODUKflva0N5BgOQkACcPWv/MVevlsdnZDjX5i1bgEGDnDvWFi163RzBBHoKUOxxIqLAtWOH7aAJkL1IDz0kA6yMDGD0aPkzLa2pN2rHDnVBEyCDhJMnnW/zgw+q7wVTy1av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wQdaN8+nBML51oq/nu+nnnoKn3zyCbZv346UlBSb+2p1voMmcIqLi0NcXJyqfSsqKpCRkYFevXph5cqVaNHCdsdceno6kpKSsHnzZvTs2ROAzDPYtm0b5syZ43LbXeHI89bCmTNncOzYMZOAwhvc+bwD4Xz37dsXer0e//73v9G7d28AwL/+9S/o9Xr069dP9eP5yvm2JCwsDL169cLmzZtx//33N27fvHkzsrKyLB7Tt29ffPrppybbNm3ahBtvvBGhoaFuba9WnHneluzdu9cnz6uWAuF8a8XfzrcQAk899RQ2bNiA4uJipKen2z1Gs/PtUCp5EKioqBBXX321uP3228Xx48fFyZMnG2/GunbtKgoLCxt/f/XVV0V0dLQoLCwU33//vRg1apRITk4WNTU1nn4KTisvLxd79+4V+fn5om3btmLv3r1i79694vz58437GD/v8+fPi7/85S9i586doqysTBQVFYm+ffuK9u3bB/TzFiIwzvfgwYPFtddeK0pKSkRJSYn44x//KO69916Tffz9fK9du1aEhoaKFStWiH379onc3FzRpk0bceTIESGEEM8//7wYM2ZM4/6//PKLaN26tZg8ebLYt2+fWLFihQgNDRUff/yxt56CUxx93vPnzxcbNmwQP//8s/jhhx/E888/LwCIgoICbz0Fp5w/f77x8wtAzJs3T+zdu1eUl5cLIQL3fDv6vAPhfD/xxBMiOjpaFBcXm1ynL1261LiPu843AyczK1euFAAs3owBECtXrmz8vaGhQcyYMUMkJSWJ8PBwcdttt4nvv//ew613TU5OjsXnXVRU1LiP8fO+dOmSyMzMFPHx8SI0NFR06NBB5OTkiKNHj3rnCTjJ0ectRGCc7zNnzoiHHnpIREZGisjISPHQQw81m54cCOf7zTffFB07dhRhYWHihhtuMJmunJOTIwYMGGCyf3FxsejZs6cICwsTaWlpYsmSJR5usTYced5z5swRnTp1EhEREeKKK64Qt956q/jss8+80GrXKNPszW85OTlCiMA9344+70A439au08b/T7vrfOv+2wAiIiIisiNoZtURERERuYqBExEREZFKDJyIiIiIVGLgRERERKQSAyciIiIilRg4EREREanEwImIiIhIJQZORERERCoxcCKioHby5EmMHj0aXbt2RYsWLZCbm+vtJhGRD2PgRERBrba2FvHx8XjxxRdx3XXXebs5ROTjGDgRUUCrrq5GUlISXnnllcZt//rXvxAWFoZNmzYhLS0NCxcuxMMPP4zo6GgvtpSI/EFLbzeAiMid4uPj8e677+K+++5DZmYmunXrhj/96U+YOHEiMjMzvd08IvIzDJyIKODdc889GDduHB566CHcdNNNiIiIwKuvvurtZhGRH+JQHREFhTfeeAP19fVYv349PvzwQ0RERHi7SUTkhxg4EVFQ+OWXX3DixAk0NDSgvLzc280hIj/FoToiCnh1dXV46KGHMGLECHTr1g2PPvoovv/+eyQmJnq7aUTkZxg4EVHAe/HFF6HX6/G///u/aNu2Lb744gs8+uij+L//+z8AQGlpKQDgwoULqK6uRmlpKcLCwnDNNdd4sdVE5It0Qgjh7UYQEblLcXEx7rzzThQVFeHWW28FABw9ehTXXnstZs+ejSeeeAI6na7ZcR07dsSRI0c83Foi8nUMnIiIiIhUYnI4ERERkUoMnIiIiIhUYuBEREREpBIDJyIiIiKVGDgRERERqcTAiYiIiEglBk5EREREKjFwIiIiIlKJgRMRERGRSgyciIiIiFRi4ERERESkEgMnIiIiIpX+P7yQe/KWaoJ4AAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def plot_dataset(X, y, title):\n",
    "    # Plot both classes: Class1->Blue, Class2->Red\n",
    "    plt.scatter(X[y==1, 0], X[y==1, 1], c='blue', label=\"class 1\")\n",
    "    plt.scatter(X[y==0, 0], X[y==0, 1], c='red', label=\"class 2\")\n",
    "    \n",
    "    # Add legend, labels, and limits\n",
    "    plt.legend(loc='upper right')\n",
    "    plt.xlabel('x1')\n",
    "    plt.ylabel('x2')\n",
    "    plt.xlim(-2, 2)\n",
    "    plt.ylim(-2, 2)\n",
    "    \n",
    "    # Set the title\n",
    "    plt.title(title)\n",
    "    \n",
    "    # Display the plot\n",
    "    plt.show()\n",
    "\n",
    "# Example of calling the function\n",
    "plot_dataset(X, y, title=\"Dataset\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Importing the necessary libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-01-09T14:42:28.491779Z",
     "start_time": "2021-01-09T14:42:28.489635Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "import time\n",
    "from torch.nn import BCELoss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We are creating the network below. We will have two hidden layers. Since the data seems easily seperable, we can have a small network (2 hidden layers) with 10 units at each layer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-01-09T14:42:28.498956Z",
     "start_time": "2021-01-09T14:42:28.494975Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "net = nn.Sequential(nn.Linear(in_features=2, out_features=10),\n",
    "                    nn.ReLU(),\n",
    "                    nn.Linear(10, 10),\n",
    "                    nn.ReLU(),\n",
    "                    nn.Linear(10, 1),\n",
    "                    nn.Sigmoid())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's define the training parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-01-09T14:42:28.504886Z",
     "start_time": "2021-01-09T14:42:28.500985Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "batch_size = 4           # How many samples to use for each weight update \n",
    "epochs = 50              # Total number of iterations\n",
    "learning_rate = 0.01     # Learning rate\n",
    "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
    "\n",
    "epochs = 50   # Total number of iterations\n",
    "lr = 0.01     # Learning rate\n",
    "\n",
    "# Define the loss. As we used sigmoid in the last layer, we use `nn.BCELoss`.\n",
    "# Otherwise we could have made use of `nn.BCEWithLogitsLoss`.\n",
    "loss = BCELoss(reduction='none')\n",
    "\n",
    "# Define the optimizer, SGD with learning rate\n",
    "optimizer = torch.optim.SGD(net.parameters(), lr=lr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-01-09T14:42:28.512093Z",
     "start_time": "2021-01-09T14:42:28.506620Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Split the dataset into two parts: 80%-20% split\n",
    "X_train, X_val = X[0:int(len(X)*0.8), :], X[int(len(X)*0.8):, :]\n",
    "y_train, y_val = y[:int(len(X)*0.8)], y[int(len(X)*0.8):]\n",
    "\n",
    "# Use PyTorch DataLoaders to load the data in batches\n",
    "train_dataset = torch.utils.data.TensorDataset(torch.tensor(X_train, dtype=torch.float32),\n",
    "                                               torch.tensor(y_train, dtype=torch.float32))\n",
    "train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size)\n",
    "\n",
    "# Move validation dataset on CPU/GPU device\n",
    "X_val = torch.tensor(X_val, dtype=torch.float32).to(device)\n",
    "y_val = torch.tensor(y_val, dtype=torch.float32).to(device)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's start the training process. We will have training and validation sets and print our losses at each step."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-01-09T14:42:32.187608Z",
     "start_time": "2021-01-09T14:42:28.513937Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0. Train_loss 0.693587 Validation_loss 0.678519 Seconds 0.104705\n",
      "Epoch 1. Train_loss 0.677538 Validation_loss 0.664652 Seconds 0.130205\n",
      "Epoch 2. Train_loss 0.661165 Validation_loss 0.640835 Seconds 0.130497\n",
      "Epoch 3. Train_loss 0.636651 Validation_loss 0.608006 Seconds 0.134795\n",
      "Epoch 4. Train_loss 0.607073 Validation_loss 0.574001 Seconds 0.132582\n",
      "Epoch 5. Train_loss 0.576680 Validation_loss 0.540941 Seconds 0.099369\n",
      "Epoch 6. Train_loss 0.538881 Validation_loss 0.495373 Seconds 0.100749\n",
      "Epoch 7. Train_loss 0.476735 Validation_loss 0.419854 Seconds 0.099384\n",
      "Epoch 8. Train_loss 0.391180 Validation_loss 0.342552 Seconds 0.098300\n",
      "Epoch 9. Train_loss 0.300648 Validation_loss 0.257315 Seconds 0.151194\n",
      "Epoch 10. Train_loss 0.207544 Validation_loss 0.171783 Seconds 0.127954\n",
      "Epoch 11. Train_loss 0.135650 Validation_loss 0.113842 Seconds 0.102826\n",
      "Epoch 12. Train_loss 0.093113 Validation_loss 0.081616 Seconds 0.106750\n",
      "Epoch 13. Train_loss 0.068840 Validation_loss 0.062823 Seconds 0.105049\n",
      "Epoch 14. Train_loss 0.054023 Validation_loss 0.050901 Seconds 0.100946\n",
      "Epoch 15. Train_loss 0.044341 Validation_loss 0.042604 Seconds 0.111017\n",
      "Epoch 16. Train_loss 0.037486 Validation_loss 0.036564 Seconds 0.189474\n",
      "Epoch 17. Train_loss 0.032416 Validation_loss 0.031970 Seconds 0.159132\n",
      "Epoch 18. Train_loss 0.028487 Validation_loss 0.028390 Seconds 0.172794\n",
      "Epoch 19. Train_loss 0.025366 Validation_loss 0.025486 Seconds 0.189952\n",
      "Epoch 20. Train_loss 0.022845 Validation_loss 0.023092 Seconds 0.291608\n",
      "Epoch 21. Train_loss 0.020768 Validation_loss 0.021103 Seconds 0.109950\n",
      "Epoch 22. Train_loss 0.019031 Validation_loss 0.019423 Seconds 0.137973\n",
      "Epoch 23. Train_loss 0.017548 Validation_loss 0.017982 Seconds 0.167709\n",
      "Epoch 24. Train_loss 0.016276 Validation_loss 0.016736 Seconds 0.133566\n",
      "Epoch 25. Train_loss 0.015168 Validation_loss 0.015647 Seconds 0.109298\n",
      "Epoch 26. Train_loss 0.014198 Validation_loss 0.014689 Seconds 0.106907\n",
      "Epoch 27. Train_loss 0.013346 Validation_loss 0.013844 Seconds 0.125602\n",
      "Epoch 28. Train_loss 0.012588 Validation_loss 0.013085 Seconds 0.125808\n",
      "Epoch 29. Train_loss 0.011907 Validation_loss 0.012401 Seconds 0.110483\n",
      "Epoch 30. Train_loss 0.011294 Validation_loss 0.011778 Seconds 0.141587\n",
      "Epoch 31. Train_loss 0.010738 Validation_loss 0.011214 Seconds 0.160476\n",
      "Epoch 32. Train_loss 0.010231 Validation_loss 0.010705 Seconds 0.100530\n",
      "Epoch 33. Train_loss 0.009770 Validation_loss 0.010234 Seconds 0.096850\n",
      "Epoch 34. Train_loss 0.009347 Validation_loss 0.009806 Seconds 0.114766\n",
      "Epoch 35. Train_loss 0.008958 Validation_loss 0.009410 Seconds 0.110252\n",
      "Epoch 36. Train_loss 0.008599 Validation_loss 0.009045 Seconds 0.178258\n",
      "Epoch 37. Train_loss 0.008267 Validation_loss 0.008705 Seconds 0.215181\n",
      "Epoch 38. Train_loss 0.007958 Validation_loss 0.008396 Seconds 0.144380\n",
      "Epoch 39. Train_loss 0.007673 Validation_loss 0.008103 Seconds 0.109694\n",
      "Epoch 40. Train_loss 0.007406 Validation_loss 0.007831 Seconds 0.102036\n",
      "Epoch 41. Train_loss 0.007157 Validation_loss 0.007574 Seconds 0.103040\n",
      "Epoch 42. Train_loss 0.006924 Validation_loss 0.007334 Seconds 0.125899\n",
      "Epoch 43. Train_loss 0.006706 Validation_loss 0.007107 Seconds 0.149604\n",
      "Epoch 44. Train_loss 0.006500 Validation_loss 0.006893 Seconds 0.154590\n",
      "Epoch 45. Train_loss 0.006306 Validation_loss 0.006691 Seconds 0.100118\n",
      "Epoch 46. Train_loss 0.006123 Validation_loss 0.006500 Seconds 0.097246\n",
      "Epoch 47. Train_loss 0.005950 Validation_loss 0.006320 Seconds 0.096599\n",
      "Epoch 48. Train_loss 0.005786 Validation_loss 0.006148 Seconds 0.177477\n",
      "Epoch 49. Train_loss 0.005631 Validation_loss 0.005989 Seconds 0.108310\n"
     ]
    }
   ],
   "source": [
    "train_losses = []\n",
    "val_losses = []\n",
    "for epoch in range(epochs):\n",
    "    start = time.time()\n",
    "    training_loss = 0\n",
    "    # Build a training loop, to train the network\n",
    "    for idx, (data, target) in enumerate(train_loader):\n",
    "        # zero the parameter gradients\n",
    "        optimizer.zero_grad()\n",
    "        \n",
    "        data = data.to(device)\n",
    "        target = target.to(device).view(-1, 1)\n",
    "        \n",
    "        output = net(data)\n",
    "        L = loss(output, target).sum()\n",
    "        training_loss += L.item()\n",
    "        L.backward()\n",
    "        optimizer.step()\n",
    "    \n",
    "    # Get validation predictions\n",
    "    val_predictions = net(X_val)\n",
    "    # Calculate the validation loss\n",
    "    val_loss = torch.sum(loss(val_predictions, y_val.view(-1, 1))).item()\n",
    "    \n",
    "    # Take the average losses\n",
    "    training_loss = training_loss / len(y_train)\n",
    "    val_loss = val_loss / len(y_val)\n",
    "    \n",
    "    train_losses.append(training_loss)\n",
    "    val_losses.append(val_loss)\n",
    "    \n",
    "    end = time.time()\n",
    "    print(\"Epoch %s. Train_loss %f Validation_loss %f Seconds %f\" % \\\n",
    "          (epoch, training_loss, val_loss, end-start))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's see the training and validation loss plots below. Losses go down as the training process continues as expected."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2021-01-09T14:42:32.401843Z",
     "start_time": "2021-01-09T14:42:32.189298Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHFCAYAAAAOmtghAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABkW0lEQVR4nO3dd3wUdf7H8dfsbnpZAiEFEgJI75AABkT0QBDLiXonNhAFPayHnGc5LMjpof4U0fPgjhPBitjPgkoQFSQWSugBUUoCJECANELK7s7vj00WlgSkJNmU9/PxmMdOZr6z+9kxmrff+c53DNM0TUREREQaCIuvCxARERGpTgo3IiIi0qAo3IiIiEiDonAjIiIiDYrCjYiIiDQoCjciIiLSoCjciIiISIOicCMiIiINisKNiIiINCgKNyJSybx58zAMg5UrV/q6lFpV8b137Njh61JE5Cwo3IiIiEiDonAjIiIiDYrCjYicse+++44hQ4YQFhZGcHAwAwYM4LPPPvNqU1RUxH333UebNm0IDAykadOmJCUlMX/+fE+bbdu2ce2119KiRQsCAgKIjo5myJAhrFmz5oSfPWPGDAzD4Jdffqm074EHHsDf35+cnBwAUlJSuOKKK4iLiyMwMJB27drxpz/9ybP/ZFq3bs3YsWMrbb/gggu44IILvLbl5+d7vqu/vz8tW7Zk4sSJHD582Kvdu+++S//+/bHb7QQHB9O2bVtuueWW36xFRE6NzdcFiEj99O2333LRRRfRo0cP5syZQ0BAADNnzuTyyy9n/vz5jBo1CoBJkybx+uuv88QTT9C7d28OHz7Mhg0bOHDggOe9LrnkEpxOJ8888wytWrUiJyeH1NRUcnNzT/j5N954Iw888ADz5s3jiSee8Gx3Op288cYbXH755URGRgLw66+/kpyczPjx47Hb7ezYsYPp06dz3nnnsX79evz8/M76fBQVFTF48GB27drF3/72N3r06MHGjRt59NFHWb9+PYsXL8YwDL7//ntGjRrFqFGjmDJlCoGBgezcuZMlS5acdQ0iUs4UETnO3LlzTcBcsWLFCduce+65ZlRUlFlQUODZ5nA4zG7duplxcXGmy+UyTdM0u3XrZo4cOfKE75OTk2MC5owZM067zquuusqMi4sznU6nZ9vChQtNwPzkk0+qPMblcpllZWXmzp07TcD83//+59lX8b23b9/u2ZaQkGDedNNNld5n8ODB5uDBgz0/T5s2zbRYLJXO2XvvvWcC5sKFC03TNM1nn33WBMzc3NzT/r4icmp0WUpETtvhw4f58ccf+cMf/kBoaKhnu9VqZfTo0ezatYstW7YA0K9fPz7//HMefPBBvvnmG44cOeL1Xk2bNuWcc87h//7v/5g+fTppaWm4XK5TquPmm29m165dLF682LNt7ty5xMTEMGLECM+2ffv2MWHCBOLj47HZbPj5+ZGQkABAenr6GZ+HY3366ad069aNXr164XA4PMvw4cMxDINvvvkGgL59+wJwzTXX8M4777B79+5q+XwROUrhRkRO26FDhzBNk9jY2Er7WrRoAeC57PTiiy/ywAMP8NFHH3HhhRfStGlTRo4cydatWwEwDIOvvvqK4cOH88wzz9CnTx+aN2/OPffcQ0FBwUnrGDFiBLGxscydO9dT18cff8yYMWOwWq0AuFwuhg0bxgcffMD999/PV199xU8//cQPP/wAUClsnam9e/eybt06/Pz8vJawsDBM0/SM7zn//PP56KOPcDgcjBkzhri4OLp16+Y1BklEzo7G3IjIaYuIiMBisZCVlVVp3549ewA8411CQkJ4/PHHefzxx9m7d6+nF+fyyy9n8+bNACQkJDBnzhwAfv75Z9555x2mTJlCaWkp//73v09YR0VP0Ysvvkhubi5vvfUWJSUl3HzzzZ42GzZsYO3atcybN4+bbrrJs72qgchVCQwMpKSkpNL2nJwcz3es+L5BQUG88sorVb7PsW2vuOIKrrjiCkpKSvjhhx+YNm0a119/Pa1btyY5OfmU6hKRE1PPjYictpCQEPr3788HH3zg1fPhcrl44403iIuLo0OHDpWOi46OZuzYsVx33XVs2bKFoqKiSm06dOjAww8/TPfu3Vm9evVv1nLzzTdTXFzM/PnzmTdvHsnJyXTq1Mmz3zAMAAICAryO+89//nNK37V169asW7fOa9vPP//suexW4bLLLuPXX3+lWbNmJCUlVVpat25d6b0DAgIYPHgwTz/9NABpaWmnVJOInJx6bkTkhJYsWVLlbL2XXHIJ06ZN46KLLuLCCy/kvvvuw9/fn5kzZ7Jhwwbmz5/vCRX9+/fnsssuo0ePHkRERJCens7rr79OcnIywcHBrFu3jrvuuos//vGPtG/fHn9/f5YsWcK6det4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bM8uwzB4cmR3OsWEkVNYyl1vrabM6fJhsSIi9dPll19+wknvvv/+ewzDYPXq1af9vitWrOC222472/K8TJkyhV69elXanpWVxYgRI6r1s443b968OvkAzDOlcOMrhgG/fwmad4bCvfDOTeAo9ewO8rcy84Y+hAbYWLHjEP/3ZeUnvIqIyMmNGzeOJUuWsHPnzkr7XnnlFXr16kWfPn1O+32bN29OcHBwdZT4m2JiYggICKiVz2ooFG58KSAUrn0TAuyQ+QN8+Tev3W2bh/LsH3sAMHvpNr7YkF3Vu4iIyAlcdtllREVFMW/ePK/tRUVFLFiwgHHjxnHgwAGuu+464uLiCA4Opnv37syfP/+k73v8ZamtW7dy/vnnExgYSJcuXUhJSal0zAMPPECHDh0IDg6mbdu2PPLII5SVlQHunpPHH3+ctWvXYhgGhmF4aj7+stT69ev53e9+R1BQEM2aNeO2226jsLDQs3/s2LGMHDmSZ599ltjYWJo1a8add97p+awzkZGRwRVXXEFoaCjh4eFcc8017N2717N/7dq1XHjhhYSFhREeHk5iYiIrV64EYOfOnVx++eVEREQQEhJC165dWbhw4RnXcipsNfru8tuanQNXzYb5o2DFf6FlH+h1vWf3xd1iGX9eG17+bjt/fXctHWPCaBMZ4sOCRUSOYZpQVlT7n+sX7O4B/w02m40xY8Ywb948Hn30UYzyY959911KS0u54YYbKCoqIjExkQceeIDw8HA+++wzRo8eTdu2benfv/9vfobL5eKqq64iMjKSH374gfz8fK/xORXCwsKYN28eLVq0YP369dx6662EhYVx//33M2rUKDZs2MAXX3zB4sWLAbDb7ZXeo6ioiIsvvphzzz2XFStWsG/fPsaPH89dd93lFeC+/vprYmNj+frrr/nll18YNWoUvXr14tZbb/3N73M80zQZOXIkISEhfPvttzgcDu644w5GjRrFN998A8ANN9xA7969mTVrFlarlTVr1uDn5wfAnXfeSWlpKUuXLiUkJIRNmzYRGhp62nWcDoWbuqDjxTD4Qfj2Kfj0XojqAi16eXY/MKITazJzWbnzELe/sYqP7hxIoJ/Vd/WKiFQoK4J/tKj9z/3bHvA/tf/Ru+WWW/i///s/vvnmGy688ELAfUnqqquuIiIigoiICO677z5P+7vvvpsvvviCd99995TCzeLFi0lPT2fHjh3ExcUB8I9//KPSOJmHH37Ys966dWv+8pe/sGDBAu6//36CgoIIDQ3FZrMRExNzws968803OXLkCK+99hohIe7v/9JLL3H55Zfz9NNPEx0dDUBERAQvvfQSVquVTp06cemll/LVV1+dUbhZvHgx69atY/v27cTHxwPw+uuv07VrV1asWEHfvn3JyMjgr3/9K506dQKgffv2nuMzMjK4+uqr6d69OwBt27Y97RpOly5L1RWDH4AOF7ufJr5gNBw+4NnlZ7Xw0vV9iAz1Z3N2AY98tMGHhYqI1C+dOnViwIABvPLKKwD8+uuvLFu2jFtuuQUAp9PJk08+SY8ePWjWrBmhoaEsWrSIjIyMU3r/9PR0WrVq5Qk2AMnJyZXavffee5x33nnExMQQGhrKI488csqfcexn9ezZ0xNsAAYOHIjL5WLLlqNjM7t27YrVevR/gmNjY9m3b99pfdaxnxkfH+8JNgBdunShSZMmpKenAzBp0iTGjx/P0KFDeeqpp/j116PztN1zzz088cQTDBw4kMcee4x169adUR2nQz03dYXFAlf+B/57IRzcBu/fAje8D1b3P6IYeyAvXtubG+f8yLurdpHUOoJRfVv5uGgRafT8gt29KL743NMwbtw47rrrLv71r38xd+5cEhISGDJkCADPPfcczz//PDNmzKB79+6EhIQwceJESktLf+Nd3aqaTd447pLZDz/8wLXXXsvjjz/O8OHDsdvtvP322zz33HOn9T1M06z03lV9ZsUloWP3uVxndtftiT7z2O1Tpkzh+uuv57PPPuPzzz/nscce4+233+bKK69k/PjxDB8+nM8++4xFixYxbdo0nnvuOe6+++4zqudUqOemLglqAqPedP9Lu+0b+HGW1+4B7SL5y7COADzyv41s2J1X+zWKiBzLMNyXh2p7OYXxNse65pprsFqtvPXWW7z66qvcfPPNnj/My5Yt44orruDGG2+kZ8+etG3blq1bt57ye3fp0oWMjAz27Dka8r7//nuvNsuXLychIYHJkyeTlJRE+/btK93B5e/vj9Pp/M3PWrNmDYcPH/Z6b4vFQocOHU655tNR8f0yMzM92zZt2kReXh6dO3f2bOvQoQP33nsvixYt4qqrrmLu3LmeffHx8UyYMIEPPviAv/zlL/z3v/+tkVorKNzUNdFd4OJp7vVv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wk033WRarVYzJCTEa5k6dappmu6nlU+YMMHrmP79+5u33367aZqmOXv2bDMiIsIsLCz07P/ss89Mi8ViZmdnm6Zpmi1atDAnT558whoA8+GHH/b8XFhYaBqGYX7++efV9j1FpHZozI2I1AkXXnghs2bN8trWtGlTz3pycrLXvuTkZNasWQNAeno6PXv2JCQkxLN/4MCBuFwutmzZgmEY7NmzhyFDhpy0hh49enjWQ0JCCAsLY9++fWf6lUTERxRuRKROCAkJqXSZ6LcYhgGAaZqe9araBAUFndL7+fn5VTrW5XKdVk0i4nsacyMi9cIPP/xQ6edOnToB0KVLF9asWcPhw4c9+5cvX47FYqFDhw6EhYXRunVrvvrqq1qtWUR8Qz03IlInlJSUkJ2d7bXNZrMRGRkJwLvvvktSUhLnnXceb775Jj/99BNz5swB4IYbbuCxxx7jpptuYsqUKezfv5+7776b0aNHEx0dDcCUKVOYMGECUVFRjBgxgoKCApYvX87dd99du19URGqcwo2I1AlffPEFsbGxXts6duzI5s2bAfedTG+//TZ33HEHMTExvPnmm3Tp0gWA4OBgvvzyS/785z/Tt29fgoODufrqq5k+fbrnvW666SaKi4t5/vnnue+++4iMjOQPf/hD7X1BEak1hmmapq+LEBE5GcMw+PDDDxk5cqSvSxGRekBjbkRERKRBUbgRERGRBkVjbkSkztPVcxE5Heq5ERERkQZF4UZEREQaFIUbERERaVAUbkRERKRBUbgRERGRBkXhRkRERBoUhRsRERFpUBRuREREpEFRuBEREZEG5f8BGYcy8CSQjD0AAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# Plot the training and validation losses\n",
    "plt.plot(train_losses, label=\"Training Loss\")\n",
    "plt.plot(val_losses, label=\"Validation Loss\")\n",
    "\n",
    "# Add title, labels, and legend\n",
    "plt.title(\"Loss values\")\n",
    "plt.xlabel(\"Epoch\")\n",
    "plt.ylabel(\"Loss\")\n",
    "plt.legend()\n",
    "\n",
    "# Display the plot\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. <a name=\"5\">Natural Language Processing Context</a>\n",
    "(<a href=\"#0\">Go to top</a>)\n",
    "\n",
    "If we want to use the same type of architecture for text classification, we need to apply some feature extraction methods first. For example: We can get TF-IDF vectors of text fields. After that, we can use neural networks on those features. \n",
    "\n",
    "We will also look at __more advanced neural network architrectures__ such as __Recurrent Neural Networks (RNNs)__, __Long Short-Term Memory networks (LSTMs)__ and __Transformers__. "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "sagemaker-distribution:Python",
   "language": "python",
   "name": "conda-env-sagemaker-distribution-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
